#include <QVector2D.h>
#include "VG/openvg.h"
#include <math.h>

#pragma once

/**
  * Ported to C++ (Qt for vector class) from original python code:
  *
# An example implementation of the algorithm described at
# http://www.niksula.cs.hut.fi/~hkankaan/Homepages/metaballs.html
#
# The code contains some references to the document above, in form
# ### Formula (x)
# to make clear where each of the formulas is implemented (and what
# it looks like in Python)
#
# Since Python doesn't have an in-built vector type, I used complex
# numbers for coordinates (x is the real part, y is the imaginary part)
#
# Made by Hannu Kankaanp��. Use for whatever you wish.
*/


class Ball
{
public:
    bool active;
    int sharedBall;
    QVector2D dir;
    QVector2D pos;
    QVector2D pos0;
    QVector2D edgePos;
    bool tracking;
    float size;


    VGubyte commands[1024];
    VGfloat vertices[1024];

    int verticeCount;

    /**Single metaball. */
    Ball(QVector2D _pos0, float size0) : pos(_pos0), size(size0), tracking(false), dir((float)(rand()&255)/128.0f-1.0f,(float)(rand()&255)/128.0f-1.0f)
    {
        dir*=40.0f;
        active = true;
    }

    Ball() : tracking(false), dir((float)(rand()&255)/128.0f-1.0f,(float)(rand()&255)/128.0f-1.0f)
    {
        size = 2.0f;
        pos = QVector2D( 0, 0);
        dir*=40.0f;
        active = true;
    }

};


/**A class that manages the metaballs and can calculate
 several useful values from the system.
*/
class MetaballSystem
{
public:
    MetaballSystem(int ballCount0, Ball *balls0, float goo0, float threshold0);
    float calcForce(QVector2D pos);
    QVector2D calcNormal(QVector2D pos);
    QVector2D calcTangent(QVector2D pos);
    float stepOnceTowardsBorder(QVector2D &pos);
    QVector2D trackTheBorder(QVector2D pos);
    QVector2D eulerTangent(QVector2D pos, float h);
    QVector2D rungeKutta2Tangent(QVector2D pos, float h);

    float minSize;
    int ballCount;
    Ball *balls;
    float goo;
    float threshold;


};




